﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace Brain.Windows
{
    public class DockManager
    {
        public List<DockingArea> DockingAreas { get; set; }

        public Control Owner;

        public GraphicalOverlay Overlay;

        public DockManager(Control control)
        {
            this.Owner = control;
            DockingAreas = new List<DockingArea>();

            Overlay = new GraphicalOverlay();
            Overlay.Owner = Owner;
            Overlay.Paint += new EventHandler<PaintEventArgs>(Overlay_Paint);
        }

        void Overlay_Paint(object sender, PaintEventArgs e)
        {
            if (movingControl)
            {
                using (Brush brush = new SolidBrush(Color.Yellow))
                {
                    for (int i = 0; i < DockingAreas.Count; i++)
                    {
                        DockingArea area = DockingAreas[i];
                        e.Graphics.FillRectangle(brush, area.CollisionArea);
                    }
                }
                if (lastArea != null)
                {
                    using (Brush brush = new SolidBrush(Color.Blue))
                    {
                        e.Graphics.FillRectangle(brush, lastArea.Value);
                    }
                }
            }
        }

        Rectangle? lastArea;
        bool movingControl = false;
        public void UserMovedControl(DockControl control)
        {
            int area;
            Rectangle? Area = GetRectangle(control, out area, false);
            if (lastArea != Area)
            {
                lastArea = Area;
                Owner.Invalidate(true);
            }
            if (!movingControl)
            {
                Owner.Invalidate(true);
            }
            movingControl = true;
        }

        public void AddDockingArea(Rectangle collision, Rectangle docked)
        {
            DockingArea area = new DockingArea();
            area.CollisionArea = collision;
            area.DockedArea = docked;
            this.DockingAreas.Add(area);
        }

        public void Resized(DockControl dock, int area)
        {
            if (DockingAreas.Count > area)
            {
                DockingArea rea = DockingAreas[area];
                rea.DockedArea = new Rectangle(rea.DockedArea.X, rea.DockedArea.Y,
                    dock.Bounds.Width, dock.Bounds.Height);
                lastArea = null;
                movingControl = false;
            }
        }


        public Rectangle? GetRectangle(DockControl dock, out int dockArea, bool invalidate)
        {
            if (invalidate)
            {
                movingControl = false;
                lastArea = null;
                Owner.Invalidate(true);
            }

            for (int i = 0; i < DockingAreas.Count; i++)
            {
                DockingArea area = DockingAreas[i];
                Rectangle r = area.CollisionArea;
                if (r.IntersectsWith(dock.Bounds))
                {
                    dockArea = i;
                    return area.DockedArea;
                }
            }
            dockArea = 0;

            return null;
        }


        public bool CanResize(DockControl dock, int dockArea, int newWidth, int newHeight)
        {
            DockingArea docked = DockingAreas[dockArea];
            Rectangle newSize = new Rectangle(dock.Location.X, dock.Location.Y, newWidth, newHeight);

            bool resize = true;
            for (int i = 0; i < DockingAreas.Count; i++)
            {
                DockingArea nearby = DockingAreas[i];
                if (i != dockArea)
                {
                    if (newSize.IntersectsWith(nearby.DockedArea) ||
                        newSize.IntersectsWith(nearby.CollisionArea))
                    {
                        resize = false;
                    }
                }
            }

            return resize;
        }
    }
}
